﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using NFit.Core.Interfaces;
using NFit.Core.BaseClasses;
using NFit.Core.IO;
using NFit.Core;

namespace NFit.Console
{
    /// <summary>
    /// Report in console
    /// </summary>
    public class ConsoleReport : BaseReportWriter
    {
        /// <summary>
        /// Make the report for the associated summary
        /// </summary>
        /// <param name="summary"></param>
        public override void Report(ExecutionSummary summary)
        {
            string strSummary = string.Format("Successfull:{0}, failed:{1} (executed in {2}ms)", summary.Successful, summary.Failed, summary.Duration.TotalMilliseconds);
            System.Console.WriteLine(strSummary);
            System.Console.WriteLine("");
            base.Report(summary);
        }

        /// <summary>
        /// Get the output stream
        /// </summary>
        /// <returns></returns>
        protected override Stream GetReportStream()
        {
            return null;
        }

        /// <summary>
        /// Write the given specification and all its childs
        /// </summary>
        /// <param name="spec"></param>
        public override void WriteSpec(SpecificationDefinition spec)
        {
            System.Console.WriteLine("runned : " + spec.Name + " " + spec.IsSuccessful + " (executed in " + spec.Status.Duration.TotalMilliseconds + "ms)");
            if (!spec.IsSuccessful)
            {
                for (int f = 0; f < spec.Count; f++ )
                {
                    var fixture = spec[f];
                    if (!fixture.IsSuccessful)
                    {
                        ReportFixture(f, fixture);
                    }
                }

            }
            WriteSpecs(spec.ChildSpecs);
        }

        private void ReportFixture(int f, FixtureDefinition fixture)
        {
            System.Console.WriteLine("fixture " + (f+1) + " failed");
            for (int r = 0; r < fixture.Count; r++)
            {
                var row = fixture[r];
                if (!row.IsSuccessful)
                {
                    System.Console.WriteLine("the following line failed");
                                
                    System.Text.StringBuilder sb = new StringBuilder();
                    System.Text.StringBuilder sbMessages = new StringBuilder();

                    System.Console.WriteLine("");

                    foreach (var cell in row)
                    {
                        if (sb.Length > 0)
                        {
                            sb.Append(" | ");
                            System.Console.Write(" | ");
                        }
                        sb.Append(cell.Text);
                        if (cell.HasErrors)
                        {
                            System.Console.ForegroundColor = ConsoleColor.Red;
                            sbMessages.AppendLine(cell.Status.NestedError.ToString());
                        }
                        else if (cell.Status.Success.HasValue)
                        {
                            System.Console.ForegroundColor = ConsoleColor.Green;
                        }
                        System.Console.Write(cell.Text);
                        System.Console.ResetColor();
                    }
                    System.Console.WriteLine("");
                    System.Console.WriteLine(sbMessages.ToString());
                }
            }
        }
    }
}
